home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / less / filename.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-04-04  |  6.2 KB  |  362 lines

  1. /*
  2.  * Routines to mess around with filenames (and files).
  3.  * Much of this is very OS dependent.
  4.  */
  5.  
  6. #include <stdio.h>
  7. #include "less.h"
  8.  
  9. extern char *getenv();
  10.  
  11. extern int force_open;
  12. extern IFILE curr_ifile;
  13. extern IFILE old_ifile;
  14.  
  15. /*
  16.  * Return the full pathname of the given file in the "home directory".
  17.  */
  18.     public char *
  19. homefile(filename)
  20.     char *filename;
  21. {
  22.     register char *pathname;
  23.     register char *homedir;
  24.  
  25.     homedir = getenv("HOME");
  26. #if __MSDOS__
  27.     /*
  28.      * Most MSDOS users do not have $HOME defined,
  29.      * so if no $HOME then look for "_less" anywhere 
  30.      * on search path (always begins at current directory).
  31.      */
  32.     if (homedir == NULL)
  33.     {
  34.         extern char *searchpath();
  35.         pathname = searchpath(filename);
  36.         if (pathname == NULL)
  37.             return (NULL);
  38.         pathname = save(pathname);
  39.     } else
  40.     {
  41.         pathname = (char *) calloc(strlen(homedir)+strlen(filename)+2, 
  42.                     sizeof(char));
  43.         if (pathname == NULL)
  44.             return (NULL);
  45.         sprintf(pathname, "%s\\%s", homedir, filename);
  46.     }
  47. #else
  48.     if (homedir == NULL)
  49.         return (NULL);
  50.     pathname = (char *) calloc(strlen(homedir)+strlen(filename)+2,
  51.                 sizeof(char));
  52.     if (pathname == NULL)
  53.         return (NULL);
  54.     sprintf(pathname, "%s/%s", homedir, filename);
  55. #endif
  56.     return (pathname);
  57. }
  58.  
  59. /*
  60.  * Find out where the help file is.
  61.  */
  62.     public char *
  63. find_helpfile()
  64. {
  65.     register char *helpfile;
  66. #if __MSDOS__
  67.     extern char *searchpath();
  68.  
  69.     /*
  70.      * Look in current directory.
  71.      */
  72.     if (access(HELPFILE,0) == 0)
  73.         return (HELPFILE);
  74.     /*
  75.      * Find the basename of HELPFILE,
  76.      * and look for it in each directory in the search path.
  77.      */
  78.     if ((helpfile = strrchr(HELPFILE, '\\')) == NULL)
  79.         helpfile = HELPFILE;
  80.     else
  81.         helpfile++;
  82.     return (save(searchpath(helpfile)));
  83. #else
  84.     if ((helpfile = getenv("LESSHELP")) != NULL)
  85.         return (save(helpfile));
  86.     return (save(HELPFILE));
  87. #endif
  88. }
  89.  
  90. /*
  91.  * Expand a string, substituting any "%" with the current filename,
  92.  * and any "#" with the previous filename.
  93.  */
  94.     public char *
  95. fexpand(s)
  96.     char *s;
  97. {
  98.     register char *fr, *to;
  99.     register int n;
  100.     register char *e;
  101.  
  102.     /*
  103.      * Make one pass to see how big a buffer we 
  104.      * need to allocate for the expanded string.
  105.      */
  106.     n = 0;
  107.     for (fr = s;  *fr != '\0';  fr++)
  108.     {
  109.         switch (*fr)
  110.         {
  111.         case '%':
  112.             n += strlen(get_filename(curr_ifile));
  113.             break;
  114.         case '#':
  115.             if (old_ifile == NULL_IFILE)
  116.             {
  117.                 error("No previous file", NULL_PARG);
  118.                 return (NULL);
  119.             }
  120.             n += strlen(get_filename(old_ifile));
  121.             break;
  122.         default:
  123.             n++;
  124.             break;
  125.         }
  126.     }
  127.  
  128.     e = (char *) ecalloc(n+1, sizeof(char));
  129.  
  130.     /*
  131.      * Now copy the string, expanding any "%" or "#".
  132.      */
  133.     to = e;
  134.     for (fr = s;  *fr != '\0';  fr++)
  135.     {
  136.         switch (*fr)
  137.         {
  138.         case '%':
  139.             strcpy(to, get_filename(curr_ifile));
  140.             to += strlen(to);
  141.             break;
  142.         case '#':
  143.             strcpy(to, get_filename(old_ifile));
  144.             to += strlen(to);
  145.             break;
  146.         default:
  147.             *to++ = *fr;
  148.             break;
  149.         }
  150.     }
  151.     *to = '\0';
  152.     return (e);
  153. }
  154.  
  155. /*
  156.  * Try to determine if a file is "binary".
  157.  * This is just a guess, and we need not try too hard to make it accurate.
  158.  */
  159.     int
  160. bin_file(f)
  161.     int f;
  162. {
  163.     int i;
  164.     int n;
  165.     char data[64];
  166.  
  167.     n = read(f, data, sizeof(data));
  168.     for (i = 0;  i < n;  i++)
  169.         if (binary_char(data[i]))
  170.             return (1);
  171.     return (0);
  172. }
  173.  
  174. /*
  175.  * Try to determine the size of a file by seeking to the end.
  176.  */
  177.     static POSITION
  178. seek_filesize(f)
  179.     int f;
  180. {
  181.     offset_t spos;
  182.  
  183.     spos = lseek(f, (offset_t)0, 2);
  184.     if (spos == BAD_LSEEK)
  185.         return (NULL_POSITION);
  186.     return ((POSITION) spos);
  187. }
  188.  
  189. /*
  190.  * Expand a filename, substituting any environment variables, etc.
  191.  */
  192. #if GLOB
  193.  
  194. FILE *popen();
  195.  
  196.     public char *
  197. glob(filename)
  198.     char *filename;
  199. {
  200.     FILE *f;
  201.     char *p;
  202.     int ch;
  203.     int len;
  204.     char *cmd;
  205.     char *gfilename;
  206.  
  207.     filename = fexpand(filename);
  208.     if (filename == NULL)
  209.         return (NULL);
  210.  
  211.     /*
  212.      * We get the shell to expand the filename for us by passing
  213.      * an "echo" command to the shell and reading its output.
  214.      */
  215.     p = getenv("SHELL");
  216.     if (p == NULL || *p == '\0')
  217.     {
  218.         /*
  219.          * Read the output of <echo filename>.
  220.          */
  221.         cmd = (char *) ecalloc(strlen(filename)+6, sizeof(char));
  222.         sprintf(cmd, "echo %s", filename);
  223.     } else
  224.     {
  225.         /*
  226.          * Read the output of <$SHELL -c "echo filename">.
  227.          */
  228.         cmd = (char *) ecalloc(strlen(p)+strlen(filename)+12, sizeof(char));
  229.         sprintf(cmd, "%s -c \"echo %s\"", p, filename);
  230.     }
  231.  
  232.     f = popen(cmd, "r");
  233.     free(cmd);
  234.     if (f == NULL)
  235.         return (filename);
  236.     free(filename);
  237.  
  238.     len = 100;
  239.     gfilename = (char *) ecalloc(len, sizeof(char));
  240.     for (p = gfilename;  ;  p++)
  241.     {
  242.         if ((ch = getc(f)) == '\n' || ch == EOF)
  243.             break;
  244.         if (p - gfilename >= len-1)
  245.         {
  246.             len *= 2;
  247.             *p = '\0';
  248.             p = (char *) ecalloc(len, sizeof(char));
  249.             strcpy(p, gfilename);
  250.             free(gfilename);
  251.             gfilename = p;
  252.             p = gfilename + strlen(gfilename);
  253.         }
  254.         *p = ch;
  255.     }
  256.     *p = '\0';
  257.     pclose(f);
  258.     if (*gfilename == '\0')
  259.         return (NULL);
  260.     return (gfilename);
  261. }
  262.  
  263. #else
  264.  
  265.     public char *
  266. glob(filename)
  267.     char *filename;
  268. {
  269.     return (fexpand(filename));
  270. }
  271.  
  272. #endif
  273.  
  274.  
  275. #if STAT
  276.  
  277. #include <sys/types.h>
  278. #include <sys/stat.h>
  279.  
  280. /*
  281.  * Returns NULL if the file can be opened and
  282.  * is an ordinary file, otherwise an error message
  283.  * (if it cannot be opened or is a directory, etc.)
  284.  */
  285.     public char *
  286. bad_file(filename)
  287.     char *filename;
  288. {
  289.     register char *m;
  290.     struct stat statbuf;
  291.  
  292.     if (stat(filename, &statbuf) < 0)
  293.         return (errno_message(filename));
  294.  
  295.     if (force_open)
  296.         return (NULL);
  297.  
  298.     if ((statbuf.st_mode & S_IFMT) == S_IFDIR)
  299.     {
  300.         static char is_dir[] = " is a directory";
  301.         m = (char *) ecalloc(strlen(filename) + sizeof(is_dir), 
  302.             sizeof(char));
  303.         strcpy(m, filename);
  304.         strcat(m, is_dir);
  305.         return (m);
  306.     }
  307.     if ((statbuf.st_mode & S_IFMT) != S_IFREG)
  308.     {
  309.         static char not_reg[] = " is not a regular file";
  310.         m = (char *) ecalloc(strlen(filename) + sizeof(not_reg), 
  311.             sizeof(char));
  312.         strcpy(m, filename);
  313.         strcat(m, not_reg);
  314.         return (m);
  315.     }
  316.  
  317.     return (NULL);
  318. }
  319.  
  320. /*
  321.  * Return the size of a file, as cheaply as possible.
  322.  * In Unix, we can stat the file.
  323.  */
  324.     public POSITION
  325. filesize(f)
  326.     int f;
  327. {
  328.     struct stat statbuf;
  329.  
  330.     if (fstat(f, &statbuf) < 0)
  331.         /*
  332.          * Can't stat; try seeking to the end.
  333.          */
  334.         return (seek_filesize(f));
  335.  
  336.     return ((POSITION) statbuf.st_size);
  337. }
  338.  
  339. #else
  340.  
  341. /*
  342.  * If we have no way to find out, just say the file is good.
  343.  */
  344.     public char *
  345. bad_file(filename)
  346.     char *filename;
  347. {
  348.     return (NULL);
  349. }
  350.  
  351. /*
  352.  * We can find the file size by seeking.
  353.  */
  354.     public POSITION
  355. filesize(f)
  356.     int f;
  357. {
  358.     return (seek_filesize(f));
  359. }
  360.  
  361. #endif
  362.